package com.cqjtu.eecs.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.cqjtu.eecs.entity.Permission;
import com.cqjtu.eecs.entity.Role;
import com.cqjtu.eecs.entity.RolePermission;
import com.cqjtu.eecs.entity.params.role.RoleParams;
import com.cqjtu.eecs.entity.vo.RolePermissionVO;
import com.cqjtu.eecs.exception.NotFoundException;
import com.cqjtu.eecs.mapper.PermissionMapper;
import com.cqjtu.eecs.mapper.RoleMapper;
import com.cqjtu.eecs.mapper.RolePermissionMapper;
import com.cqjtu.eecs.mapper.RoleUserMapper;
import com.cqjtu.eecs.service.IRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqjtu.eecs.utils.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色 服务实现类
 * </p>
 *
 * @author  luojun
 * @since 2022-03-04
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private RolePermissionMapper rolePermissionMapper;
    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    private RoleUserMapper roleUserMapper;

    /**
     * 通过角色名获取角色权限
     * @param name  角色名
     * @return
     */
    @Override
    public List<RolePermissionVO> queryRolePermissionByName(String name) {
        Role role = roleMapper.selectOne(new LambdaQueryWrapper<Role>().eq(Role::getRoleName, name));
        Assert.notNull(role,new NotFoundException("Not find the role"));
        List<RolePermission> rolePermissions = rolePermissionMapper.selectList(new LambdaQueryWrapper<RolePermission>()
                .eq(RolePermission::getRoleId, role.getRoleId()));
        List<RolePermissionVO> rolePermissionVOS = new ArrayList<>();
        // 获取全部权限
        List<Permission> allPermissions = permissionMapper.selectList(null);
        if (rolePermissions.isEmpty()) {
            allPermissions.forEach(item->{
                rolePermissionVOS.add(new RolePermissionVO(
                        item.getTitle(),
                        item.getIcon(),
                        false,
                        new ArrayList<RolePermissionVO>()
                ));
            });
            return rolePermissionVOS;
        }
        List<Permission> permissions = permissionMapper
                .selectBatchIds(rolePermissions.stream().map(RolePermission::getId).collect(Collectors.toList()));
        Set<Integer> idSet = permissions.stream().map(Permission::getId).collect(Collectors.toSet());
        HashMap<Integer, RolePermissionVO> hashMap = new HashMap<>();
        allPermissions.forEach(item->{
            if (null == item.getParent()){
                hashMap.put(item.getId(),new RolePermissionVO(item.getTitle(),
                        item.getIcon(),
                        idSet.contains(item.getId()),
                        new ArrayList<RolePermissionVO>()));
            }else{
                // 最多二级标题
                hashMap.get(item.getParent())
                        .getChildren()
                        .add(new RolePermissionVO(item.getTitle(),
                                item.getIcon(),
                                idSet.contains(item.getId()),
                                new ArrayList<RolePermissionVO>()));
            }
        });
        hashMap.forEach((key, value)->{
            rolePermissionVOS.add(value);
        });
        return rolePermissionVOS;
    }

    /**
     * 更新角色的权限
     * @param name
     * @param permissions
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateRolePermission(String name, List<String> permissions) {
        Role role = roleMapper.selectOne(new LambdaQueryWrapper<Role>().eq(Role::getRoleName, name));
        Assert.notNull(role, new NotFoundException("Not find the role"));
        // 获取角色的已有权限
        List<RolePermission> rolePermissions = rolePermissionMapper.selectList(new LambdaQueryWrapper<RolePermission>()
                .eq(RolePermission::getRoleId, role.getRoleId()));
        List<Permission> permissionArrayList; // 已有权限
        if (rolePermissions.isEmpty()){
            permissionArrayList = new ArrayList<>();
        }else{
            permissionArrayList = permissionMapper
                    .selectBatchIds(rolePermissions.stream().map(RolePermission::getId).collect(Collectors.toList()));
        }
        Set<String> newPermission = new HashSet<>(permissions);
        Set<String> oldPermission;
        if (permissionArrayList.isEmpty()){
            oldPermission = new HashSet<>();
        }else{
            oldPermission = permissionArrayList.stream().map(Permission::getTitle).collect(Collectors.toSet());
        }
        // 获取全部权限的映射
        Map<String, Integer> map = permissionMapper
                .selectList(null)
                .stream()
                .collect(Collectors.toMap(Permission::getTitle, Permission::getId));
        System.out.println(map);
        List<RolePermission> list = new ArrayList<>();
        // 获取新加入的
        newPermission.removeAll(oldPermission);
        Iterator<String> iterator = newPermission.iterator();
        while (iterator.hasNext()){
            list.add(new RolePermission(map.get(iterator.next()),role.getRoleId()));
        }
        if (!list.isEmpty())
            rolePermissionMapper.saveBath(list);
        // 获取需要删除的
        oldPermission.removeAll(new HashSet<>(permissions));
        Iterator<String> iterator1 = oldPermission.iterator();
        ArrayList<Integer> integers = new ArrayList<>();
        while (iterator1.hasNext()){
            integers.add(map.get(iterator1.next()));
        }
        if (!integers.isEmpty())
            rolePermissionMapper.deleteByRidAndPid(role.getRoleId(), integers);
        return true;
    }

    /**
     * 添加角色
     * @param roleParams
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addRole(RoleParams roleParams) {
        if (!this.save(new Role(null, roleParams.getRoleName())))
            return false;
        if (!roleParams.getRolePermissions().isEmpty()){
            return this.updateRolePermission(roleParams.getRoleName(), roleParams.getRolePermissions());
        }
        return true;
    }

    /**
     * 根据用户id获取用户角色List
     * @param id
     * @return
     */
    @Override
    public List<String> listUserRole(Integer id) {
        return roleMapper.listUserRole(id);
    }
}
